﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Collections.Specialized;
using System.Net;
using OAuth;
using OAuth.ServiceProviders;
using log4net;
using WebUtils;

namespace YammerAPI
{
    public class ApiWrapper
    {
        static readonly ILog Log = LogManager.GetLogger(typeof(ApiWrapper));

        public ApiWrapper(
            string pConsumerKey,
            string pConsumerSecret,
            IAccessTokenStorage pTokenStorage,
            Func<string, string> pUserAuthRedirection)
        {
            if (Log.IsDebugEnabled)
            {
                var sb = new StringBuilder();
                sb.Append("Creating the Yammer API class:" + Environment.NewLine);
                sb.AppendFormat("Consumer Token: {0}, Consemer Secret: {1}", pConsumerKey, pConsumerSecret);
                Log.Debug(sb.ToString());
            }

            OAuthSession = OAuth.OAuthSessionHelper.GetSession(new YammerSessionParameter(
                pConsumerKey,
                pConsumerSecret,
                pTokenStorage,
                pUserAuthRedirection));
        }

        public void StartSession(bool pReset)
        {
            if (pReset)
                OAuthSession.RefreshSession();
            else
                OAuthSession.StartSession();
        }

        public IOAuthSession OAuthSession { get; private set; }

        class YammerWebRequest : WebUtils.HttpRequest
        {
        }

        #region Messages

        /// <summary>
        /// All messages in this network. Corresponds to the "All" tab on the website.
        /// </summary>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public List<Message> GetAllMessages()
        {
            return RetrieveMessages(Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
            {
                Address = Resources.YAMMER_MESSAGES_ALL,
                Verb = WebMethodVerbEnum.GET
            })));
        }

        /// <summary>
        /// Corresponds to the "All" tab on the website. 
        /// </summary>
        /// <param name="newer_than"></param>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public List<Message> GetAllMessages(PageFlag pFlag, int pId)
        {
            return RetrieveMessages(Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
            {
                Address = Resources.YAMMER_MESSAGES_ALL,
                Verb = WebMethodVerbEnum.GET,
                GetParameters = new UnEncodedURLParameter[] 
                {
                    new UnEncodedURLParameter() { 
                        Key = pFlag == PageFlag.NEWER_THAN 
                            ? "newer_than" 
                            : "older_than", 
                        Value = pId.ToString() }
                }
            })));
        }


        /// <summary>
        /// Corresponds to the "Sent" tab on the website.
        /// </summary>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public List<Message> GetSentMessages()
        {
            return RetrieveMessages(Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
            {
                Address = Resources.YAMMER_MESSAGES_SENT,
                Verb = WebMethodVerbEnum.GET
            })));
        }

        /// <summary>
        /// Corresponds to the "Sent" tab on the website.
        /// </summary>
        /// <param name="flag"></param>
        /// <param name="thread"></param>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public List<Message> GetSentMessages(PageFlag pFlag, int pId)
        {
            return RetrieveMessages(Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
            {
                Address = Resources.YAMMER_MESSAGES_SENT,
                Verb = WebMethodVerbEnum.GET,
                GetParameters = new UnEncodedURLParameter[] 
                {
                    new UnEncodedURLParameter() { 
                        Key = pFlag == PageFlag.NEWER_THAN 
                            ? "newer_than" 
                            : "older_than", 
                        Value = pId.ToString() }
                }
            })));
        }

        /// <summary>
        /// Messages received by the logged-in user. Corresponds to the "Received" tab on the website.
        /// </summary>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public List<Message> GetReceivedMessages()
        {
            return RetrieveMessages(Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
            {
                Address = Resources.YAMMER_MESSAGES_RECEIVED,
                Verb = WebMethodVerbEnum.GET
            })));
        }

        /// <summary>
        /// Messages received by the logged-in user. Corresponds to the "Received" tab on the website.
        /// </summary>
        /// <param name="flag"></param>
        /// <param name="thread"></param>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public List<Message> GetReceivedMessages(PageFlag pFlag, int pId)
        {
            return RetrieveMessages(Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
            {
                Address = Resources.YAMMER_MESSAGES_RECEIVED,
                Verb = WebMethodVerbEnum.GET,
                GetParameters = new UnEncodedURLParameter[] 
                {
                    new UnEncodedURLParameter() { 
                        Key = pFlag == PageFlag.NEWER_THAN 
                            ? "newer_than" 
                            : "older_than", 
                        Value = pId.ToString() }
                }
            })));
        }

        /// <summary>
        /// Messages followed by the logged-in user. Corresponds to the "Following" tab on the website.
        /// </summary>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public List<Message> GetFollowingMessages()
        {
            return RetrieveMessages(Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
            {
                Address = Resources.YAMMER_MESSAGES_FOLLOWING,
                Verb = WebMethodVerbEnum.GET
            })));
        }

        /// <summary>
        /// Messages followed by the logged-in user. Corresponds to the "Following" tab on the website.
        /// </summary>
        /// <param name="flag"></param>
        /// <param name="date"></param>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public List<Message> GetFollowingMessages(PageFlag pFlag, int pId)
        {
            return RetrieveMessages(Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
            {
                Address = Resources.YAMMER_MESSAGES_FOLLOWING,
                Verb = WebMethodVerbEnum.GET,
                GetParameters = new UnEncodedURLParameter[] 
                {
                    new UnEncodedURLParameter() { 
                        Key = pFlag == PageFlag.NEWER_THAN 
                            ? "newer_than" 
                            : "older_than", 
                        Value = pId.ToString() }
                }
            })));
        }

        /// <summary>
        /// Messages sent by the user with the given ID. Corresponds to the messages on a user profile page on the website.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public List<Message> GetMessagesSentBy(int pId)
        {
            return RetrieveMessages(Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
            {
                Address = Resources.YAMMER_MESSAGES_SENT_BY + pId.ToString() + ".xml",
                Verb = WebMethodVerbEnum.GET
            })));
        }

        /// <summary>
        /// Messages including the tag with given ID. Corresponds to the messages on a tag's page on the website.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public List<Message> GetMessagesTaggedWith(int id)
        {
            return RetrieveMessages(Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
            {
                Address = Resources.YAMMER_MESSAGES_TAGGED_WITH + id.ToString() + ".xml",
                Verb = WebMethodVerbEnum.GET
            })));
        }

        /// <summary>
        /// Messages in the thread with the given ID. Corresponds to the page you'd see when clicking on "in reply to" on the website.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public List<Message> GetMessagesInThread(int id)
        {
            return RetrieveMessages(Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
            {
                Address = Resources.YAMMER_MESSAGES_IN_THREAD + id.ToString(),
                Verb = WebMethodVerbEnum.GET
            })));
        }

        /// <summary>
        /// Messages in the group with the given ID. Corresponds to the messages you'd see on a group's profile page.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public List<Message> GetMessagesInGroup(int id)
        {
            return RetrieveMessages(Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
            {
                Address = Resources.YAMMER_MESSAGES_IN_GROUP + id.ToString() + ".xml",
                Verb = WebMethodVerbEnum.GET
            })));
        }

        /// <summary>
        /// Favorite messages of the given user ID. Can pass 'current' in place of user_id for currently logged in user
        /// </summary>
        /// <param name="id"></param>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public List<Message> GetMessagesFavoritesOf(int id)
        {
            return RetrieveMessages(Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
            {
                Address = Resources.YAMMER_MESSAGES_FAVORITES_OF + id.ToString() + ".xml",
                Verb = WebMethodVerbEnum.GET
            })));
        }

        /// <summary>
        /// Create a new message.
        /// </summary>
        /// <param name="body"></param>
        /// <param name="IOAuthSession"></param>
        public void PostMessage(string body, ICollection<string> attachments)
        {
            // if we have only a body, we'll put the body in a post parameter
            // otherwise we do the mime thing
            if (attachments == null || attachments.Count == 0)
            {
                var response = Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
                    {
                        Address = Resources.YAMMER_MESSAGES_CREATE,
                        Verb = WebMethodVerbEnum.POST,
                        PostParameters = new UnEncodedURLParameter[] { new UnEncodedURLParameter() { Key = "body", Value = body } },
                        Headers = new Parameter[] { new Parameter() { Key = "Content-Type", Value = "application/x-www-form-urlencoded" } }
                    }),
                    request =>
                    {
                        // we have to write the request body in the upload stream
                        var bodyContent = WebUtils.Utils.BuildURLEncodedParameter(
                            new UnEncodedURLParameter[]  { new UnEncodedURLParameter() { Key = "body", Value = body } },
                            false);
                        var bodyBytes = Encoding.UTF8.GetBytes(bodyContent);
                        request.ContentLength = bodyBytes.Length;

                        using(var requestStream = request.GetRequestStream())
                        {
                            requestStream.Write(bodyBytes, 0, bodyBytes.Length);
                            requestStream.Close();
                        }
                    });

                if (response.Contains("favicon.ico"))
                {
                    // i'm not sure, but it seems as if yammer doesn't fail
                    // when you try to post a message and it's not authed
                    // so we try to detect a fail here
                    throw new SystemException("It appears as if you are not authorized to perform this action");
                }
            }
            else
            {
                throw new NotImplementedException();
                Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
                {
                    Address = Resources.YAMMER_MESSAGES_CREATE,
                    Verb = WebMethodVerbEnum.POST,
                    Headers = new Parameter[] { new Parameter() {  Key = "Content-Type", Value = "application/x-www-form-urlencoded"} }
                }));
            }
        }

        /// <summary>
        /// Create a new message in reply to message of given id
        /// </summary>
        /// <param name="body"></param>
        /// <param name="reply"></param>
        /// <param name="IOAuthSession"></param>
        public void PostMessage(string body, int id, List<string> attachments)
        {
            // if we have only a body, we'll put the body in a post parameter
            // otherwise we do the mime thing
            if (attachments != null && attachments.Count > 0)
            {
                Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
                {
                    Address = Resources.YAMMER_MESSAGES_CREATE,
                    Verb = WebMethodVerbEnum.POST,
                    PostParameters = new UnEncodedURLParameter[] 
                    { 
                        new UnEncodedURLParameter() { Key = "body", Value = body },
                        new UnEncodedURLParameter() { Key = "replied_to_id", Value = id.ToString() }
                    }
                }));
            }
            else
            {
                throw new NotImplementedException();
                Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
                {
                    Address = Resources.YAMMER_MESSAGES_CREATE,
                    Verb = WebMethodVerbEnum.POST
                }));
            }
        }


        /// <summary>
        /// Delete a message owned by the current user.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="IOAuthSession"></param>
        public void DeleteMessage(int id)
        {
            Utils.CallWeb(OAuthSession.SignWebRequest(new YammerWebRequest()
            {
                Address = Resources.YAMMER_MESSAGES_DELETE + id.ToString(),
                Verb = WebMethodVerbEnum.DELETE
            }));
        }

        #endregion

        /*

        #region Groups

        
        /// <summary>
        /// Retrieves a list of all groups
        /// </summary>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public List<Group> GetAllGroups()
        {
            string response = Yammer.HttpUtility.Get(Resources.YAMMER_GROUP_LIST, IOAuthSession);
            XmlDocument xdoc = new XmlDocument();
            xdoc.LoadXml(response);

            XmlNodeList nodes = xdoc.SelectNodes("/response/response");
            List<Group> groups = new List<Group>();
            foreach (XmlNode node in nodes)
            {
                Group group = (Group)Deserialize(typeof(Group), "<group>" + node.InnerXml + "</group>");
                groups.Add(group);
            }
            return groups;

        }

        /// <summary>
        /// Retrieves data about group of given id
        /// </summary>
        /// <param name="id"></param>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public Group GetGroupById(int id)
        {
            string response = Yammer.HttpUtility.Get(Resources.YAMMER_GROUP_DATA + id.ToString() + ".xml", IOAuthSession);
            XmlDocument xdoc = new XmlDocument();
            xdoc.LoadXml(response);
            XmlNode node = xdoc.SelectSingleNode("/response");
            Group group = (Group)Deserialize(typeof(Group), "<group>" + node.InnerXml + "</group>");
            return group;
        }

        /// <summary>
        /// Join a group.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="IOAuthSession"></param>
        public void JoinGroup(int id)
        {
            GroupMembership(id, IOAuthSession);
        }

        /// <summary>
        /// Leave a group.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="IOAuthSession"></param>
        public void LeaveGroup(int id)
        {
            GroupMembership(id, IOAuthSession);
            
        }

        private static void GroupMembership(int id)
        {
            NameValueCollection parameters = new NameValueCollection();
            parameters.Add("group_id", id.ToString());
            Yammer.HttpUtility.Post(Resources.YAMMER_GROUP_JOIN + id.ToString() + ".xml", parameters, IOAuthSession);
        }


        #endregion

        #region Users

        /// <summary>
        /// Retreives data about current user
        /// </summary>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public User GetCurrentUser()
        {
            string response = Yammer.HttpUtility.Get(Resources.YAMMER_USERS_CURRENT, IOAuthSession);
            XmlDocument xdoc = new XmlDocument();
            xdoc.LoadXml(response);
            XmlNode node = xdoc.SelectSingleNode("/response");
            User user = (User)Deserialize(typeof(User), "<reference>" + node.InnerXml + "</reference>");
            return user;
        }

        /// <summary>
        /// Retrieves data about user of given id
        /// </summary>
        /// <param name="id"></param>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public User GetUserById(int id)
        {
            string response = Yammer.HttpUtility.Get(Resources.YAMMER_USERS_SINGLE + id.ToString() + ".xml", IOAuthSession);
            XmlDocument xdoc = new XmlDocument();
            xdoc.LoadXml(response);
            XmlNode node = xdoc.SelectSingleNode("/response");
            User user = (User)Deserialize(typeof(User), "<reference>" + node.InnerXml + "</reference>");
            return user;
        }

        /// <summary>
        /// Retrieves list of users in network
        /// </summary>
        /// <param name="IOAuthSession"></param>
        /// <returns></returns>
        public List<User> GetAllUsers()
        {
            string response = Yammer.HttpUtility.Get(Resources.YAMMER_USERS_ALL, IOAuthSession);
            XmlDocument xdoc = new XmlDocument();
            xdoc.LoadXml(response);
            XmlNodeList nodes = xdoc.SelectNodes("/response/response");
            List<User> users = new List<User>();
            foreach (XmlNode node in nodes)
            {
                User user = (User)Deserialize(typeof(User), "<reference>" + node.InnerXml + "</reference>");
                users.Add(user);
            }
            return users;
        }
        #endregion

        #region Relationships

        /// <summary>
        /// Retrieves org chart relationships.
        /// </summary>
        /// <param name="IOAuthSession"></param>
        public void GetAllRelationships()
        {
            string response = Yammer.HttpUtility.Get(Resources.YAMMER_RELATIONSHIPS_ALL, IOAuthSession);
        }

        /// <summary>
        /// Creates a new org chart relationship
        /// </summary>
        /// <param name="type"></param>
        /// <param name="email"></param>
        /// <param name="IOAuthSession"></param>
        public void CreateRelationship(RelationshipType type, string email)
        {
            NameValueCollection parameters = new NameValueCollection();
            parameters.Add(type.ToString().ToLower(), email);
            Yammer.HttpUtility.Post(Resources.YAMMER_RELATIONSHIPS_CREATE, parameters, IOAuthSession);
        }

        /// <summary>
        /// Deletes org chart relationship
        /// NOT YET IMPLEMENTED
        /// </summary>
        public void DeleteRelationship()
        {
            throw new System.NotImplementedException();
        }

        #endregion

        #region Suggestions

        /// <summary>
        /// Returns list of all suggested groups and users
        /// NOT YET IMPLEMENTED
        /// </summary>
        /// <param name="IOAuthSession"></param>
        public void GetAllSuggestions()
        {
            string response = Yammer.HttpUtility.Get(Resources.YAMMER_SUGGESTIONS_SHOW_ALL, IOAuthSession);
        }

        #endregion

        #region Subscriptions

        /// <summary>
        /// Subscribe to user
        /// </summary>
        /// <param name="id"></param>
        /// <param name="IOAuthSession"></param>
        public void SubscribeToUser(int id)
        {
            NameValueCollection parameters = new NameValueCollection();
            parameters.Add("target_type", "user");
            parameters.Add("target_id", id.ToString());
            string data = Yammer.HttpUtility.Post(Resources.YAMMER_SUBSCRIPTIONS_SUBSCRIBE, parameters, IOAuthSession);
        }

        /// <summary>
        /// Subscribe to tag
        /// </summary>
        /// <param name="id"></param>
        /// <param name="IOAuthSession"></param>
        public void SubscribeToTag(int id)
        {
            NameValueCollection parameters = new NameValueCollection();
            parameters.Add("target_type", "tag");
            parameters.Add("target_id", id.ToString());
            string data = Yammer.HttpUtility.Post(Resources.YAMMER_SUBSCRIPTIONS_SUBSCRIBE, parameters, IOAuthSession);
        }

        /// <summary>
        /// Unsubscribe to user
        /// </summary>
        /// <param name="id"></param>
        /// <param name="IOAuthSession"></param>
        public void DeleteSubscriptionToUser(int id)
        {
            string data = Yammer.HttpUtility.Delete(Resources.YAMMER_RELATIONSHIPS_DELETE + "?target_type=user" + "&target_id=" + id.ToString(), IOAuthSession);
        }

        /// <summary>
        /// Unsubscribe to tag
        /// </summary>
        /// <param name="id"></param>
        /// <param name="IOAuthSession"></param>
        public void DeleteSubscriptionToTag(int id)
        {
            string data = Yammer.HttpUtility.Delete(Resources.YAMMER_RELATIONSHIPS_DELETE + "?target_type=tag" + "&target_id=" + id.ToString(), IOAuthSession);
        }

        #endregion
        */

        #region Helper Methods

        private static object Deserialize(Type type, string xml)
        {

            XmlSerializer serializer = new XmlSerializer(type);
            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            byte[] bytes = encoding.GetBytes(xml);
            System.IO.MemoryStream stream = new MemoryStream(bytes);
            object obj = (object)serializer.Deserialize(stream);

            return obj;

        }

        private static void SetMessageReference(Message message, Message reference)
        {
            if (message != null)
                message.References.Messages.Add(reference);
            
        }

        private static void SetMessageReference(Message message, Guide reference)
        {
            if (message != null)
                message.References.Guide = reference;
        }

        private static void AddMessageReferences(List<Message> messages, object reference)
        {
            if (messages != null)
            {
                User user;
                Tag tag;
                Thread thread;
                foreach (Message msg in messages)
                {
                    switch (ConvertReferenceType(reference, out user, out tag, out thread))
                    {
                        case ObjectType.USER:
                            msg.References.Users.Add(user);
                            break;
                        case ObjectType.THREAD:
                            msg.References.Thread = thread;
                            break;
                        case ObjectType.TAG:
                            msg.References.Tags.Add(tag);
                            break;
                    }
                }
            }

        }

        private static ObjectType ConvertReferenceType(object reference, out User user, out Tag tag, out Thread thread)
        {
            user = null;
            tag = null;
            thread = null;
            user = reference as User;
            ObjectType type = ObjectType.NONE;
            bool converted = false;
            if (user != null) { converted = true; type = ObjectType.USER; }
            if (!converted)
            {
                thread = reference as Thread;
                if (thread != null) { converted = true; type = ObjectType.THREAD; }
                if (!converted)
                {
                    tag = reference as Tag;
                    if (tag != null) { converted = true; type = ObjectType.TAG; }
                }
            }

            return type;
        }

        private static List<Message> RetrieveMessages(string data)
        {
            List<Message> messages = null;
            XmlDocument xdoc = new XmlDocument();
            if (Log.IsInfoEnabled)
                Log.Info("Reading XML Doc");
            xdoc.LoadXml(data);
            messages = new List<Message>();

            ReadMessages(messages, xdoc);
            ReadReferences(messages, xdoc);

            return messages;
        }

        private static void ReadReferences(List<Message> messages, XmlDocument xdoc)
        {

            if (Log.IsInfoEnabled)
                Log.Info("Reading References...");
            foreach (XmlNode node in xdoc.SelectNodes("/response/references/reference"))
            {
                string xml = node.OuterXml;
                if (Log.IsDebugEnabled)
                    Log.DebugFormat("Found Reference:\n{0}", xml);
                ObjectType objectType = (ObjectType)Enum.Parse(typeof(ObjectType), node.SelectSingleNode("type").InnerText, true);
                switch (objectType)
                {
                    case ObjectType.MESSAGE:
                        Message message = (Message)Deserialize(typeof(Message), "<message>" + node.InnerXml + "</message>");
                        SetMessageReference(messages.Find(delegate(Message m) { return m.RepliedToId == message.Id; }), message);
                        break;
                    case ObjectType.USER:
                        User user = (User)Deserialize(typeof(User), node.OuterXml);
                        AddMessageReferences(messages.FindAll(delegate(Message m) { return m.SenderId.ToString() == user.Id || m.RepliedToId == user.Id; }), user);
                        break;
                    case ObjectType.TAG:
                        Tag tag = (Tag)Deserialize(typeof(Tag), node.OuterXml);
                        string tagText = "[[tag:" + tag.Id + "]] tag";
                        AddMessageReferences(messages.FindAll(delegate(Message m) { return m.Body.Parsed.Contains(tagText); }), tag);
                        break;
                    case ObjectType.THREAD:
                        Thread thread = (Thread)Deserialize(typeof(Thread), node.OuterXml);
                        AddMessageReferences(messages.FindAll(delegate(Message m) { return m.ThreadId == thread.Id; }), thread);
                        break;
                    case ObjectType.GUIDE:
                        Guide guide = (Guide)Deserialize(typeof(Guide), node.OuterXml);
                        SetMessageReference(messages.Find(delegate(Message m) { return m.SenderId.ToString() == guide.Id; }), guide);
                        break;
                    default:
                        break;
                }
            }
            if (Log.IsInfoEnabled)
                Log.Info("Done Reading Messages");
        }

        private static void ReadMessages(List<Message> messages, XmlDocument xdoc)
        {
            if (Log.IsInfoEnabled)
                Log.Info("Reading messages...");
            var parser = new XMLParsers.MessageXMLParser();
            foreach (XmlNode mnode in xdoc.SelectNodes("/response/messages/message"))
            {
                if (Log.IsDebugEnabled)
                    Log.Debug(mnode.OuterXml);
                
                var message = parser.Parse(mnode.OuterXml);

                message.References = new Reference();
                messages.Add(message);
            }
            if (Log.IsInfoEnabled)
                Log.Info("Finished reading messages.");
        }

        #endregion

    }
}
